package com.android.people;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import android.content.Context;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.net.Uri;
import android.provider.MediaStore.Images;
import android.provider.MediaStore.Images.Media;
import android.util.Log;

public class ImageListManager {
    private static final String TAG = "ImageListManager";
    private static final boolean DEBUG = false;    
    
    private static final String[] ACCEPTABLE_IMAGE_TYPES =
        new String[] { "image/jpeg", "image/png", "image/gif" };
    private static final String WHERE_CLAUSE = "(" + Media.MIME_TYPE + " in (?, ?, ?))";
    private static final Uri STORAGE_URI = Images.Media.EXTERNAL_CONTENT_URI;
    static final String[] IMAGE_PROJECTION = new String[] {
        Media._ID,
        Media.DATA,
        Media.DATE_TAKEN,
        Media.MINI_THUMB_MAGIC,
        Media.ORIENTATION,
        Media.TITLE,
        Media.MIME_TYPE,
        Media.DATE_MODIFIED};

    private static final int INDEX_ID = 0;
    private static final int INDEX_DATA_PATH = 1;
    private static final int INDEX_DATE_TAKEN = 2;
    private static final int INDEX_MINI_THUMB_MAGIC = 3;
    private static final int INDEX_ORIENTATION = 4;
    private static final int INDEX_TITLE = 5;
    private static final int INDEX_MIME_TYPE = 6;
    private static final int INDEX_DATE_MODIFIED = 7;
    
    
    private final String mScanPath;
    private Context mContext;
    private Cursor mCursor;
    private Map<Long, Integer> mIdToOrentationMap;
    
    public ImageListManager(Context context, String scanPath) {
        mScanPath = scanPath;
        mContext = context;
        mIdToOrentationMap = new HashMap<Long, Integer>();
        LOGD("path = " + mScanPath);
        mCursor = createCursor();
        filterByPath();
    }
    
    public List<Long> getIDList() {
        List<Long> ret = new ArrayList<Long>();
        for (Long id : mIdToOrentationMap.keySet()) {
            ret.add(id);
        }
        return ret;
    }
    
    public Bitmap thumbBitmap(long id) {
        Bitmap bitmap = null;
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inDither = false;
        options.inPreferredConfig = Bitmap.Config.ARGB_8888;
        bitmap = Images.Thumbnails.getThumbnail(
                    mContext.getContentResolver(), id, Images.Thumbnails.MINI_KIND, options);

        int orentation = mIdToOrentationMap.get(id);
        if (bitmap != null && orentation != 0) {
            bitmap = rotate(bitmap, orentation);
        }

        return bitmap;
    }

    public void refreshList() {
        if (mCursor != null) {
            mCursor.close();
        }
        mCursor = createCursor();
        filterByPath(); 
//        LOGD("????????????????????????????????????????????????");
//        dump();
    }
    
    public void dump() {
        LOGD("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^");
        if (mCursor == null) {
            return ;
        }
        mCursor.moveToFirst();
        int count = mCursor.getCount();
        for (int index = 0; index < count; ++index) {
            long id = mCursor.getLong(INDEX_ID);
            String dataPath = mCursor.getString(INDEX_DATA_PATH);
            String mimeType = mCursor.getString(INDEX_MIME_TYPE);
            LOGD("for the index = " + index + " id = " + id + "  path = " + dataPath + " mimeType = " + mimeType);
            mCursor.moveToNext();
        }
        LOGD("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^");
    }
    
    private Bitmap rotate(Bitmap b, int degrees) {
        if (degrees != 0 && b != null) {
            Matrix m = new Matrix();
            m.setRotate(degrees,
                    (float) b.getWidth() / 2, (float) b.getHeight() / 2);
            try {
                Bitmap b2 = Bitmap.createBitmap(
                        b, 0, 0, b.getWidth(), b.getHeight(), m, true);
                if (b != b2) {
                    b.recycle();
                    b = b2;
                }
            } catch (OutOfMemoryError ex) {
                // We have no memory to rotate. Return the original bitmap.
            }
        }
        return b;
    }
    
    private void filterByPath() {
        if (mCursor != null) {
            mIdToOrentationMap.clear();
            mCursor.moveToFirst();
            int count = mCursor.getCount();
            for (int index = 0; index < count; ++index) {
                String datapath = mCursor.getString(INDEX_DATA_PATH);
                if (datapath != null) {
//                    LOGD("check file = " + datapath);
                    if (datapath.startsWith(mScanPath) == true) {
                        LOGD("add file = " + datapath + " into list, the orentation = " + mCursor.getInt(INDEX_ORIENTATION));
                        mIdToOrentationMap.put(mCursor.getLong(INDEX_ID), mCursor.getInt(INDEX_ORIENTATION));
                    }
                }
                mCursor.moveToNext();
            }
        }
    }
    
    private Cursor createCursor() {
        try {
            Cursor c = Media.query(
                    mContext.getContentResolver(), STORAGE_URI, IMAGE_PROJECTION,
                    WHERE_CLAUSE, ACCEPTABLE_IMAGE_TYPES, null);
            return c;
        } catch (Exception e) {
            LOGD("error to query image" + e.getMessage());
        }
        return null;
    }
    
    //=================================================================
    public static void LOGD(String msg) {
        if (DEBUG) {
            Log.d(TAG, msg);
        }
    }
    
    public static String getCurrentTime() {
        Calendar cl = Calendar.getInstance();
        return cl.get(Calendar.HOUR_OF_DAY) + "H " + cl.get(Calendar.MINUTE) + "M "
                + cl.get(Calendar.SECOND) + "S " + cl.get(Calendar.MILLISECOND) + "ms";
    }
}
